﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using WebServer.DTO;
using Newtonsoft.Json;
using System.Text;
using System.Net;
using Microsoft.AspNetCore.Http;
using System.Threading;

namespace WebServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private readonly IHttpContextAccessor httpContextAccessor;
        public ValuesController(IHttpContextAccessor _httpContextAccessor)
        {
            httpContextAccessor = _httpContextAccessor;

            //GameDebug.Log($"ValuesController itor :{_httpContextAccessor?.HttpContext}");
        }

        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "value1", "value2" };
        }

        //static Dictionary<string, string> announceDict = new Dictionary<string, string>();

        static Dictionary<string, string> gameVersionDict = new Dictionary<string, string>();

        public static void RefreshGameVersion()
        {
            GameDebug.Log("更新 GameVersion");

            gameVersionDict = new Dictionary<string, string>();
        }

        // GET api/values/5
        [HttpGet("game_version")]
        public ActionResult<string> GameVersion(string lang)
        {
            LanguageType languageType;
            Enum.TryParse(lang, out languageType);


            string localizationAnnounce = WebServerController.Instance.GetAnnouce(languageType);//WebServerController.Instance.GetLocalizationValue(languageType, gv.announce);

            // string ip = this.httpContextAccessor.HttpContext.Request.Host.Host;

            //暂不考虑白名单
            //string ip = ServerUtility.GetIpWithIpAddress(this.httpContextAccessor.HttpContext.Connection.RemoteIpAddress);

            ////GameDebug.Log($"客户端IP：{ip}   RemoteIpAddress:{this.httpContextAccessor.HttpContext.Connection.RemoteIpAddress}");

            //if (WebServerController.Instance.GetWhiteList().Contains(ip))
            //{
            //    GameDebug.Log($"在白名单里");

            //    gv.in_white_list = true;
            //}

            //if (announceDict == null)
            //    announceDict = new Dictionary<string, string>();
            if (gameVersionDict == null)
                gameVersionDict = new Dictionary<string, string>();

            //if (!announceDict.ContainsKey(lang))
            //{
            //    announceDict[lang] = "";
            //}
            if (string.IsNullOrEmpty(lang))
            {
                lang = "EN";
            }
            //if(announceDict[lang] == localizationAnnounce)
            {
                //没有变化，直接从缓存中获取数据
                if (gameVersionDict.ContainsKey(lang))
                {
                    //有缓存
                    return gameVersionDict[lang];
                }
                else
                {
                    GameVersion gv = GameVersionDataManager.Instance.gameVersion;
                    gv.announce = localizationAnnounce;
                    gameVersionDict[lang] = GetEncodeGameVersionStr(gv);
                    return gameVersionDict[lang];
                }
            }
            //else
            //{
            //    //有变化，更新
            //    announceDict[lang] = localizationAnnounce;

            //    GameVersion gv = GameVersionDataManager.Instance.gameVersion;
            //    gv.announce = localizationAnnounce;
            //    gameVersionDict[lang] = GetEncodeGameVersionStr(gv);
            //    return gameVersionDict[lang];
            //}
        }

        string GetEncodeGameVersionStr(GameVersion gv)
        {
            string res = JsonConvert.SerializeObject(gv);
            byte[] data = Encoding.UTF8.GetBytes(res);
            byte[] encryData = AES256Encode.AESEncode(data, SharedConfig.GameVersionAESKey, Encoding.UTF8);
            return Convert.ToBase64String(encryData);
        }

        [HttpGet("setting_notice")]
        public ActionResult<string> SettingNotice(string lang)
        {
            LanguageType languageType;
            Enum.TryParse(lang, out languageType);

            string value = WebServerController.Instance.GetNotice(languageType);
            if (!string.IsNullOrEmpty(value))
            {
                //value = WebServerController.Instance.GetLocalizationValue(languageType, key);
                byte[] data = Encoding.UTF8.GetBytes(value);
                byte[] encryData = AES256Encode.AESEncode(data, SharedConfig.GameVersionAESKey, Encoding.UTF8);
                value = Convert.ToBase64String(encryData);
            }
            return value;
        }

        [HttpGet("game_debug_info")]
        public ActionResult<string> GameDebugInfo(int id)
        {
            string res = GetDebugInfo().Result;

            //GameDebugInfo gameDebugInfo = s_gameDebugInfo;

            //lock (baton)
            //{
            //    res = gameDebugInfo.ToString();
            //}
            return Content(res, "text/html");// Content(res, "text/html"); up
        }
        async Task<string> GetDebugInfo()
        {
            string res = "";

            bool getResult = false;
            WebServerController.Instance.GetDebugInfo((text) =>
            {
                GameDebug.Log($"拿到DebugInfo结果:{text}");
                getResult = true;
                res = text;
            });
            await Task.Run(() =>
            {
                int count = 0;
                while (!getResult)
                {
                    GameDebug.Log("等待结果");
                    Thread.Sleep(100);

                    count++;
                    if (count > 100)
                    {
                        GameDebug.Log("拿DebugInfo超时");
                        break;
                    }
                }
            });
            return res;
        }

        #region web maintain

        public const string maintain_password = "BycalGin@1992";

        /// <summary>
        /// 踢出用户
        /// </summary>
        /// <param name="kickOutData"></param>
        /// <returns></returns>
        // PUT api/values/5
        [HttpPost("kickoutuser")]
        public ActionResult<string> KickOutUser(/*[FromBody]*/ KickOutDataDTO kickOutData)
        {
            if (kickOutData.password != maintain_password)
            {
                GameDebug.Log($"密码不正确：{kickOutData?.password}");
                return Conflict("password not correct");
            }

            GameDebug.Log($"移除用户：{kickOutData?.userId}");

            WebServerController.Instance.SendKickOutUser(kickOutData.userId);

            return Ok();
        }

        /// <summary>
        /// 踢出所有用户
        /// </summary>
        /// <param name="webMaintainDTO"></param>
        /// <returns></returns>
        [HttpGet("kickoutalluser")]
        public ActionResult<string> KickOutAllUser(string password, bool from_peer)// KickOutAllDataDTO webMaintainDTO)
        {
            string pass = password;
            bool fromPeer = from_peer;

            if (pass != maintain_password)
            {
                GameDebug.Log($"密码不正确：{pass}");
                return Conflict("password not correct");
            }
            GameDebug.Log($"移除所有用户");

            WebServerController.Instance.SendKickOutAllUser();

            if (!fromPeer)
            {
                //string localIP = Server.GetLocalIP();

                GameDebug.Log($"向其他服务器请求");

                foreach (WebServerController.ServerPeer peer in WebServerController.Instance.serverPeers)
                {
                    string KickOutUserUrl = $"http://{peer.host}:5000/api/values/kickoutalluser";

                    WebUtility.HttpGet(KickOutUserUrl, new Dictionary<string, object>
                    {
                        { "from_peer",true},
                        { "password",ServerConfig.MasterInterfacePassword}
                    }, 10,
                    (code, res) =>
                    {
                        if (code == HttpStatusCode.OK)
                        {
                            GameDebug.Log($"KickOutAllUser peer:{peer.host}  response:{res}");
                        }
                        else
                        {
                            GameDebug.Log($"KickOutAllUser peer failed:{peer.host}  :{code}");
                        }
                    },
                    (error) =>
                    {
                        GameDebug.Log($"KickOutAllUser peer:{peer.host}  error:{error}");
                    }
                );

                    //    AsyncHttpRequest asyncHttp = new AsyncHttpRequest(KickOutUserUrl);

                    //    asyncHttp.onResponse = (req) =>
                    //    {
                    //        if (string.IsNullOrEmpty(req.error))
                    //        {
                    //            GameDebug.Log($"KickOutAllUser peer:{peer.host}  response:{req.response}");
                    //        }
                    //        else
                    //        {
                    //            GameDebug.Log($"KickOutAllUser peer  failed:{peer.host}  error:{req.error}");
                    //        }
                    //    };

                    //    asyncHttp.POSTForm(new Dictionary<string, object>
                    //{
                    //    { "from_peer",true},
                    //    { "password",ServerConfig.MasterInterfacePassword}
                    //});
                }
            }

            return Ok();
        }


        // GET api/values/5
        //[HttpGet("maintain_with_config")]
        //public ActionResult<string> maintain_with_config()
        //{
        //    GameVersion gv = GameVersionDataManager.Instance.gameVersion; 

        //    GameDebug.Log($"维护 MaintainWithConfig：{gv.announce}   结束时间：{ gv.maintain_end_time}");

        //    SendMaintain(gv.announce, gv.maintain_end_time);

        //    return JsonConvert.SerializeObject(gv);
        //}

        /// <summary>
        /// 维护
        /// </summary>
        /// <param name="maintainData"></param>
        /// <returns></returns>
        // PUT api/values/5
        [HttpPost("maintain")]
        public ActionResult<string> Maintain(MaintainDataDTO maintainData)
        {
            if (maintainData.password != maintain_password)
            {
                GameDebug.Log($"密码不正确：{maintainData?.password}");
                return Conflict("password not correct");
            }
            GameDebug.Log($"维护：{maintainData.content}   结束时间：{maintainData.maintainEndTime}");

            GameVersion gv = GameVersionDataManager.Instance.gameVersion;
            gv.maintain_end_time = maintainData.maintainEndTime;
            //gv.announce = maintainData.content;

            WebServerController.Instance.SetAnnouce(LanguageType.CN, maintainData.content_cn);
            WebServerController.Instance.SetAnnouce(LanguageType.EN, maintainData.content_en);
            WebServerController.Instance.SetAnnouce(LanguageType.TC, maintainData.content_tc);

            string newGvStr = JsonConvert.SerializeObject(gv);
            System.IO.File.WriteAllText(ServerConfig.gameVersionPath, newGvStr);
            GameDebug.Log($"保存数据到本地,   annouce  cn:{maintainData.content_cn}   en:{maintainData.content_en}    tc:{maintainData.content_tc} ");

            SendMaintain(maintainData.content, maintainData.maintainEndTime);

            WebServerController.Instance.SendWhiteListToLogic();

            return Ok();
        }

        /// <summary>
        /// 公告
        /// </summary>
        /// <param name="maintainData"></param>
        /// <returns></returns>
        [HttpPost("announce")]
        public ActionResult<string> Announce(ContentDataDTO maintainData)
        {
            if (maintainData.password != maintain_password)
            {
                GameDebug.Log($"密码不正确：{maintainData?.password}");
                return Conflict("password not correct");
            }
            GameDebug.Log($"公告：{maintainData.content_cn}");

            WebServerController.Instance.SetAnnouce(LanguageType.CN, maintainData.content_cn);
            WebServerController.Instance.SetAnnouce(LanguageType.EN, maintainData.content_en);
            WebServerController.Instance.SetAnnouce(LanguageType.TC, maintainData.content_tc);

            return Ok();
        }

        void SendMaintain(string content, double maintainEndTime)
        {
            MaintainData maintain = new MaintainData();

            maintain.content = content;
            maintain.maintainEndTime = maintainEndTime;

            WebServerController.Instance.SendMaintain(maintain);
        }


        /// <summary>
        /// 设置界面的告示
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        [HttpPost("settingnotice")]
        public ActionResult<string> SetSettingNotice(ContentDataDTO text)
        {
            if (text.password != maintain_password)
            {
                GameDebug.Log($"密码不正确：{text?.password}");
                return Conflict("password not correct");
            }
            GameDebug.Log($"SetSettingNotice：{text.content_cn}");

            WebServerController.Instance.SetNotice(LanguageType.CN, text.content_cn.Replace("\\n", "\n"));
            WebServerController.Instance.SetNotice(LanguageType.EN, text.content_en.Replace("\\n", "\n"));
            WebServerController.Instance.SetNotice(LanguageType.TC, text.content_tc.Replace("\\n", "\n"));

            return Ok();
        }

        [HttpPost("compensate")]
        public ActionResult<string> Compensate(CompensateDataDTO compenstaeData)
        {
            if (compenstaeData.password != maintain_password)
            {
                GameDebug.Log($"密码不正确：{compenstaeData?.password}");
                return Conflict("password not correct");
            }
            GameDebug.Log($"發放维护補償：{compenstaeData.diamond}   时间：{compenstaeData.date}");

            CompensateDiamondData compensate = new CompensateDiamondData();

            compensate.diamond = compenstaeData.diamond;
            compensate.date = compenstaeData.date;

            WebServerController.Instance.SendCompensate(compensate);

            return Ok();
        }

        /// <summary>
        /// 添加白名单
        /// </summary>
        /// <param name="stringData"></param>
        /// <returns></returns>
        [HttpPost("add2whitelist")]
        public ActionResult<string> Add2WhiteList(StringDataDTO stringData)
        {
            if (stringData.password != maintain_password)
            {
                GameDebug.Log($"密码不正确：{stringData?.password}");
                return Conflict("password not correct");
            }
            GameDebug.Log($"添加白名单：{stringData.content}");

            WebServerController.Instance.Add2WhiteList(stringData.content);
            WebServerController.Instance.SendWhiteListToLogic();

            return Ok();
        }
        #endregion

        // POST api/values
        [HttpPost("checkuserexist")]
        public ActionResult<string> CheckUserExist(CheckUserExistParamDTO data)
        {
            GameDebug.Log($"请求查询用户是否在本服数据库：{data.username}");

            Data.WebResponData res = new Data.WebResponData();

            device existUser = MysqlFunction.FindInTable<device>(ServerConfig.DBShared, SqlTable.device, "uuid", data.username);
            if (existUser != null)
            {
                GameDebug.Log($"在此");
                res.code = 0;
            }
            else
            {
                res.code = -1;
            }
            return JsonConvert.SerializeObject(res);
            /* WebServerController.Instance.SendCheckUserExistFromMaster(new CheckExistUserRequestData { uuid = data.username }, (exist) =>
             {

             });*/
        }

        #region IAPCallback

        [HttpGet("iapcallback")]
        public ActionResult<string> IAPCallback(UDPIAPCallbackDTO data)
        {
            GameDebug.Log($"收到支付回调数据：{data?.payload}  \n{data?.signature}");

            return Ok();
        }

        [HttpGet("testgetorder")]
        public ActionResult<string> TestQueryingOrders()
        {
            string channelProductId = "";


            return Ok();
        }

        #endregion

    }
}

